/**
 * @file protocol.h
 * @brief 通信协议接口定义
 * @details 定义了与服务器通信的协议接口和相关数据结构
 */
#ifndef PROTOCOL_H
#define PROTOCOL_H

#include <cJSON.h>
#include <string>
#include <functional>
#include <chrono>

/**
 * @brief 二进制协议头结构
 * @details 用于二进制数据传输的协议头定义
 */
struct BinaryProtocol3 {
    uint8_t type;          ///< 消息类型
    uint8_t reserved;      ///< 保留字段
    uint16_t payload_size; ///< 负载大小
    uint8_t payload[];     ///< 可变长度负载数据
} __attribute__((packed));

/**
 * @brief 中止语音输出的原因枚举
 */
enum AbortReason {
    kAbortReasonNone,             ///< 无原因
    kAbortReasonWakeWordDetected  ///< 检测到唤醒词
};

/**
 * @brief 监听模式枚举
 */
enum ListeningMode {
    kListeningModeAutoStop,    ///< 自动停止监听
    kListeningModeManualStop,  ///< 手动停止监听
    kListeningModeRealtime     ///< 实时监听模式（需要 AEC 支持）
};

/**
 * @brief 通信协议基类
 * @details 定义了与服务器通信的基本接口和功能
 */
class Protocol {
public:
    /**
     * @brief 虚析构函数
     */
    virtual ~Protocol() = default;

    /**
     * @brief 获取服务器采样率
     * @return int 服务器采样率
     */
    inline int server_sample_rate() const {
        return server_sample_rate_;
    }
    
    /**
     * @brief 获取服务器帧持续时间
     * @return int 帧持续时间(毫秒)
     */
    inline int server_frame_duration() const {
        return server_frame_duration_;
    }
    
    /**
     * @brief 获取会话ID
     * @return const std::string& 会话ID
     */
    inline const std::string& session_id() const {
        return session_id_;
    }

    /**
     * @brief 设置接收音频数据的回调函数
     * @param callback 回调函数
     */
    void OnIncomingAudio(std::function<void(std::vector<uint8_t>&& data)> callback);
    
    /**
     * @brief 设置接收JSON数据的回调函数
     * @param callback 回调函数
     */
    void OnIncomingJson(std::function<void(const cJSON* root)> callback);
    
    /**
     * @brief 设置音频通道打开的回调函数
     * @param callback 回调函数
     */
    void OnAudioChannelOpened(std::function<void()> callback);
    
    /**
     * @brief 设置音频通道关闭的回调函数
     * @param callback 回调函数
     */
    void OnAudioChannelClosed(std::function<void()> callback);
    
    /**
     * @brief 设置网络错误的回调函数
     * @param callback 回调函数
     */
    void OnNetworkError(std::function<void(const std::string& message)> callback);

    /**
     * @brief 启动协议
     */
    virtual void Start() = 0;
    
    /**
     * @brief 打开音频通道
     * @return bool 是否成功
     */
    virtual bool OpenAudioChannel() = 0;
    
    /**
     * @brief 关闭音频通道
     */
    virtual void CloseAudioChannel() = 0;
    
    /**
     * @brief 检查音频通道是否已打开
     * @return bool 是否已打开
     */
    virtual bool IsAudioChannelOpened() const = 0;
    
    /**
     * @brief 发送音频数据
     * @param data 音频数据
     */
    virtual void SendAudio(const std::vector<uint8_t>& data) = 0;
    
    /**
     * @brief 发送唤醒词检测事件
     * @param wake_word 检测到的唤醒词
     */
    virtual void SendWakeWordDetected(const std::string& wake_word);
    
    /**
     * @brief 发送开始监听事件
     * @param mode 监听模式
     */
    virtual void SendStartListening(ListeningMode mode);
    
    /**
     * @brief 发送停止监听事件
     */
    virtual void SendStopListening();
    
    /**
     * @brief 发送中止语音输出事件
     * @param reason 中止原因
     */
    virtual void SendAbortSpeaking(AbortReason reason);
    
    /**
     * @brief 发送物联网设备描述信息
     * @param descriptors 设备描述JSON字符串
     */
    virtual void SendIotDescriptors(const std::string& descriptors);
    
    /**
     * @brief 发送物联网设备状态信息
     * @param states 设备状态JSON字符串
     */
    virtual void SendIotStates(const std::string& states);

protected:
    std::function<void(const cJSON* root)> on_incoming_json_;           ///< 接收JSON数据的回调函数
    std::function<void(std::vector<uint8_t>&& data)> on_incoming_audio_; ///< 接收音频数据的回调函数
    std::function<void()> on_audio_channel_opened_;                     ///< 音频通道打开的回调函数
    std::function<void()> on_audio_channel_closed_;                     ///< 音频通道关闭的回调函数
    std::function<void(const std::string& message)> on_network_error_;  ///< 网络错误的回调函数

    int server_sample_rate_ = 24000;                                    ///< 服务器采样率
    int server_frame_duration_ = 60;                                    ///< 服务器帧持续时间(毫秒)
    bool error_occurred_ = false;                                       ///< 是否发生错误
    std::string session_id_;                                            ///< 会话ID
    std::chrono::time_point<std::chrono::steady_clock> last_incoming_time_; ///< 最后一次接收数据的时间

    /**
     * @brief 发送文本数据
     * @param text 要发送的文本
     * @return bool 是否发送成功
     */
    virtual bool SendText(const std::string& text) = 0;
    
    /**
     * @brief 设置错误状态
     * @param message 错误信息
     */
    virtual void SetError(const std::string& message);
    
    /**
     * @brief 检查是否超时
     * @return bool 是否超时
     */
    virtual bool IsTimeout() const;
};

#endif // PROTOCOL_H
